

#include "gd32w51x.h"


#if 0
#define  DWT_CR      *(volatile uint32_t *)0xE0001000
#define  DWT_CYCCNT  *(volatile uint32_t *)0xE0001004
#define  DEM_CR      *(volatile uint32_t *)0xE000EDFC

#define  DEM_CR_TRCENA                   (1 << 24)
#define  DWT_CR_CYCCNTENA                (1 <<  0)

extern uint32_t SystemCoreClock;
/**
  * @brief  初始化时间戳
  * @param  无
  * @retval 无
  * @note   使用延时函数前，必须调用本函数
  */
void CPU_InitTick(void)
{ 
    /* 使能DWT外设 */
    DEM_CR |= (uint32_t)DEM_CR_TRCENA;                

    /* DWT CYCCNT寄存器计数清0 */
    DWT_CYCCNT = (uint32_t)0u;

    /* 使能Cortex-M DWT CYCCNT寄存器 */
    DWT_CR |= (uint32_t)DWT_CR_CYCCNTENA;	
}

/**
  * @brief  读取当前时间戳
  * @param  无
  * @retval 当前时间戳，即DWT_CYCCNT寄存器的值
  */
uint32_t CPU_Tick(void)
{        
  return ((uint32_t)DWT_CYCCNT);
}


static void SysTickDelay(uint32_t us){
  uint32_t ticks;
  uint32_t told,tnow;
  
  //ticks = us * (SystemCoreClock / 1000000);  /* 计算需要的节拍数 */     
  ticks = us * (rcu_clock_freq_get(CK_SYS)/1000000);
  told = CPU_Tick(); /* 刚进入时的计数器值 */
  do{
    tnow = CPU_Tick();
  }while((tnow - told) < ticks);
}

void BSP_Delay_ns(unsigned int ns_100)
{
	for (; ns_100 > 0; ns_100--) {
		NP();
		NP();
		NP();
	}
}


void BSP_Delay_us(uint32_t us)
{	
	SysTickDelay(us);
}


void BSP_Delay_ms(uint32_t ms)
{
		SysTickDelay(ms * 1000);
	//BSP_Sleep_Ms(ms);
}
#endif 


#if 1

#define DLY_TIMER				TIMER15
#define DLY_TIMER_RCU			RCU_TIMER15
#define DLY_TIMER_CLK_FREQ()	(rcu_clock_freq_get(CK_APB2) * 2)

static void delay_timer_config(void){
    timer_parameter_struct timer_initpara;
	uint32_t uclk = DLY_TIMER_CLK_FREQ();
	uint32_t psc = uclk / (100U*10000U);

    rcu_periph_clock_enable(DLY_TIMER_RCU);

    timer_deinit(DLY_TIMER);
    /* initialize TIMER init parameter struct */
    timer_struct_para_init(&timer_initpara);
    /* TIMER1 configuration */
    timer_initpara.prescaler         = psc - 1;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 0xFFFF;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_init(DLY_TIMER, &timer_initpara);

    timer_enable(DLY_TIMER);
}


void BSP_StrictDelay_Init(void){
}

static volatile uint8_t delay_init_flag = 0;

void BSP_StrictDelay_us(uint16_t us){
	if(delay_init_flag == 0){
		delay_init_flag = 1;
		delay_timer_config();
	}
	uint16_t c1 = timer_counter_read(DLY_TIMER);
	uint16_t c;
	do{
		c = timer_counter_read(DLY_TIMER);
	}while((c - c1) < us);
}

void BSP_Delay_us(uint32_t us)
{	
	while(us > 60000U){
		BSP_StrictDelay_us(60000U);
		us -= 60000U;
	}

	if(us > 0U){
		BSP_StrictDelay_us(us);
	}
}


void BSP_Delay_ms(uint32_t ms)
{
	BSP_Delay_us(ms * 1000U);
}


#endif 


